package com.ruizhong.centercontroll.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruizhong.centercontroll.controller.CommandController;
import com.ruizhong.centercontroll.dao.TButtonMapper;
import com.ruizhong.centercontroll.dao.TCommandMapper;
import com.ruizhong.centercontroll.entity.*;

import com.ruizhong.centercontroll.server.WebSocketServer;
import com.ruizhong.centercontroll.service.TCommandService;
import com.ruizhong.centercontroll.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.script.*;
import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static ch.qos.logback.core.encoder.ByteArrayUtil.hexStringToByteArray;

@Service
public class TCommandServiceImpl extends ServiceImpl<TCommandMapper, TCommand> implements TCommandService {


    /**
     * @param mainType mainId commandType
     * @return
     * @Description: 根据指令ID删除对应指令
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:17
     */
    @Override
    public void removeCommandByMain(String mainType, Integer mainId, String commandType) {
        QueryWrapper<TCommand> deleteWrapper = new QueryWrapper<>();
        deleteWrapper
                .lambda()
                .eq(TCommand::getMainType, mainType)
                .eq(TCommand::getCommandEvent, commandType)
                .eq(TCommand::getMainId, mainId);
        remove(deleteWrapper);
    }

    public static Map<String, List> getCommandsByGraph(Map logicGraph) {
        if (CollectionUtils.isEmpty(logicGraph)) {
            return Collections.EMPTY_MAP;
        }
        List<Map<String, Object>> cells = (List<Map<String, Object>>) logicGraph.get("cells");
        HashMap<String, List<Map<String, Object>>> shapeMapNodes = new HashMap<>();
        HashMap<String, Map<String, Object>> idMapCell = new HashMap<>();

        for (Map<String, Object> cell : cells) {
            String shape = cell.get("shape").toString();
            List<Map<String, Object>> nodeList = shapeMapNodes.get(shape);
            if (CollectionUtils.isEmpty(nodeList)) {
                nodeList = new ArrayList<>();
                shapeMapNodes.put(shape, nodeList);
            }
            nodeList.add(cell);
            idMapCell.put(cell.get("id").toString(), cell);
        }

        List<Map<String, Object>> edgeList = shapeMapNodes.get("edge");
        if (CollectionUtils.isEmpty(edgeList)) {
            return Collections.EMPTY_MAP;
        }
        final Map<String, String> typeMapfirstCommandId = new HashMap<>();
        edgeList.forEach(new Consumer<Map<String, Object>>() {
            @Override
            public void accept(Map<String, Object> edge) {
                Map<String, String> curNodeSource = (Map<String, String>) edge.get("source");
                String lastCellId = curNodeSource.get("cell");
                Map<String, Object> sourceCell = idMapCell.get(lastCellId);
                Map<String, String> curNodeTarget = (Map<String, String>) edge.get("target");
                String nextCellId = curNodeTarget.get("cell");
                Map<String, Object> targetCell = idMapCell.get(nextCellId);

                String sourcePort = curNodeSource.get("port");
                String targetPort = curNodeTarget.get("port");
                if (lastCellId.equals("release") || lastCellId.equals("init") || lastCellId.equals("switch") || lastCellId.equals("slide")) {
                    typeMapfirstCommandId.put(lastCellId, nextCellId);
                }
                if ((sourcePort.equals("nextStep") || sourcePort.equals("true") || sourcePort.equals("false")) && targetPort.equals("lastStep")) {
                    sourceCell.put("next", nextCellId);
                    if (sourcePort.equals("true")) {
                        sourceCell.put("true", nextCellId);
                    }
                    if (sourcePort.equals("false")) {
                        sourceCell.put("false", nextCellId);
                    }
//                    后节点处理

                    Map<String, String> data = (Map<String, String>) targetCell.get("data");
                    String targetShape = targetCell.get("shape").toString();
                    Map<String, Object> tCommand = getCommandByX6Data(targetShape, data);
                    targetCell.put("command", tCommand);
                } else if (sourcePort.equals("result") && targetPort.equals("input")) {
                    Map<String, String> nodeData = (Map<String, String>) targetCell.get("data");
                    ArrayList<Map<String, String>> returnValueArr = new ArrayList<>();
                    HashMap<String, String> variableMap = new HashMap<>();
                    variableMap.put("valueName", nodeData.get("beChangedVariableName"));
                    returnValueArr.add(variableMap);
                    sourceCell.put("returnValueArr", returnValueArr);
                } else if (sourcePort.equals("output")) {
                    List<String> variableList = (List<String>) targetCell.get("variableList");
                    if (variableList == null) {
                        variableList = new ArrayList<>();
                        targetCell.put("variableList", variableList);
                    }
                    variableList.add(targetPort);
                }
            }
        });
        HashMap<String, List> resMap = new HashMap<>();

        List<Map<String, Object>> rectList = shapeMapNodes.get("rect");
        rectList.forEach(new Consumer<Map<String, Object>>() {
            @Override
            public void accept(Map<String, Object> nodeMap) {
                Object nextCellId = nodeMap.get("next");
                if (nextCellId == null) {
                    return;
                }
                String firstCommandId = typeMapfirstCommandId.get(nodeMap.get("id"));
                ArrayList<Map<String, Object>> commandList = new ArrayList<>();
                createCommandList(nextCellId, idMapCell, firstCommandId, commandList);
                resMap.put(nodeMap.get("id") + "CommandList", commandList);
            }
        });
        return resMap;
    }

    private static void createCommandList(Object nextCellId, HashMap<String, Map<String, Object>> idMapCell, String firstCommandId, ArrayList<Map<String, Object>> commandList) {
        if (nextCellId == null) {
            return;
        }
        Map<String, Object> curNode = idMapCell.get(nextCellId.toString());
        Boolean added = (Boolean) curNode.get("added");
        if (added != null && added) {
            return;
        }
        Map<String, Object> tCommand = (Map<String, Object>) curNode.get("command");
        List<String> variableList = (List<String>) curNode.get("variableList");
        tCommand.put("commandId", nextCellId);
        tCommand.put("nextCommandId", curNode.get("next"));
        tCommand.put("trueNextId", curNode.get("true"));
        tCommand.put("falseNextId", curNode.get("false"));
        tCommand.put("firstCommandId", firstCommandId);
        if (!CollectionUtils.isEmpty(variableList)) {
            StringBuffer variableListString = new StringBuffer();
            for (String s : variableList) {
                variableListString.append(s + "#");
            }
            tCommand.put("variableList", variableListString.toString());
        }
        if (curNode.get("returnValueArr") != null) {
            tCommand.put("returnValueArr", curNode.get("returnValueArr"));
            tCommand.put("returnFormat", "?");
            tCommand.put("getReturn", true);
        } else {
            tCommand.put("getReturn", false);
        }
        commandList.add(tCommand);
        curNode.put("added", true);
        if (!curNode.get("shape").equals("IfElseComponent")) {
            createCommandList(curNode.get("next"), idMapCell, firstCommandId, commandList);
        } else {
            createCommandList(curNode.get("true"), idMapCell, firstCommandId, commandList);
            createCommandList(curNode.get("false"), idMapCell, firstCommandId, commandList);
        }
    }


    private static Map<String, Object> getCommandByX6Data(String shape, Map<String, String> data) {
        Map<String, Object> tCommand = new HashMap<>();
        switch (shape) {
            case "NetWorkComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("instructionData", data.get("instructionData"));
                tCommand.put("ipAddress", data.get("ipAddress"));
                tCommand.put("port", data.get("port"));
                tCommand.put("eventType", data.get("eventType"));
                tCommand.put("sonEventType", data.get("sonEventType"));
                tCommand.put("requestPath", data.get("requestPath"));
                tCommand.put("hexadecimal", data.get("hexadecimal"));
                break;
            case "VariableAssignmentComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("beChangedVariableName", data.get("beChangedVariableName"));
                tCommand.put("beChangedVariableValue", data.get("beChangedVariableValue"));
                tCommand.put("eventType", 3);
                break;
            case "ButtonCombinationComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 4);
                tCommand.put("triggerGroup", data.get("triggerGroup"));
                break;
            case "SerialCommunicationComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 6);
                tCommand.put("serialNumber", data.get("serialNumber"));
                tCommand.put("baudRate", data.get("baudRate"));
                tCommand.put("dataBits", data.get("dataBits"));
                tCommand.put("stopBits", data.get("stopBits"));
                tCommand.put("parityBits", data.get("parityBits"));
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "AudioPlayBackComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 5);
                tCommand.put("audioFilePath", data.get("audioFilePath"));
                break;
            case "CodeComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 9);
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "WakeComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 10);
                tCommand.put("instructionData", data.get("instructionData"));
                tCommand.put("ipAddress", data.get("ipAddress"));
                break;
            case "IfElseComponent":

                tCommand.put("eventType", 11);
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "ComponentStyleComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 12);
                tCommand.put("componentType", data.get("componentType"));
                tCommand.put("componentId", data.get("componentId"));
                tCommand.put("y", data.get("y"));
                tCommand.put("x", data.get("x"));
                tCommand.put("w", data.get("w"));
                tCommand.put("h", data.get("h"));
                tCommand.put("z", data.get("z"));
                tCommand.put("fontColor", data.get("fontColor"));
                tCommand.put("textChinese", data.get("textChinese"));
                tCommand.put("textTraditional", data.get("textTraditional"));
                tCommand.put("textEnglish", data.get("textEnglish"));
                tCommand.put("backgroundColor", data.get("backgroundColor"));
                tCommand.put("background", data.get("background"));
                tCommand.put("fontSize", data.get("fontSize"));
                tCommand.put("borderCorner", data.get("borderCorner"));
                break;
            case "CMDComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 8);
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "MessageComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 13);
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "PresetSettingComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 14);
                tCommand.put("bufferTime", data.get("bufferTime"));
                tCommand.put("beChangedVariableName", data.get("beChangedVariableName"));
                tCommand.put("initialValue", data.get("initialValue"));
                tCommand.put("targetValue", data.get("targetValue"));
                break;
            case "ToggleSwitchComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 15);
                tCommand.put("componentId", data.get("componentId"));
                tCommand.put("instructionData", data.get("instructionData"));
                break;
            case "VariableTriggerComponent":
                tCommand.put("delay", data.get("delay"));
                tCommand.put("eventType", 16);
                tCommand.put("beChangedVariableName", data.get("beChangedVariableName"));
                tCommand.put("instructionData", data.get("instructionData"));
                tCommand.put("inputOutputArr", data.get("inputOutputArr"));
                break;
        }
        return tCommand;
    }

    /**
     * @param type commandType slideIdMapCommandList
     * @return
     * @Description: 保存指令列表
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:19
     */
    @Override
    @Transactional
    public void saveCommandList(String type, String commandType, HashMap<Integer, List<Map<String, Object>>> sliderIdMapCommandList) {
        ArrayList<TCommand> tCommandList = new ArrayList<>();
        sliderIdMapCommandList.forEach(new BiConsumer<Integer, List<Map<String, Object>>>() {
            @Override
            public void accept(Integer componentId, List<Map<String, Object>> maps) {
                removeCommandByMain(type, componentId, commandType);
                if (maps == null || CollectionUtils.isEmpty(maps)) {
                    return;
                }
                for (int i = 0; i < maps.size(); i++) {
                    Map<String, Object> map = maps.get(i);
                    Object returnFormat = map.get("returnFormat");
                    Object beChangedVariableName = map.get("beChangedVariableName");
                    Object beChangedVariableValue = map.get("beChangedVariableValue");
                    Object instructionData = map.get("instructionData");
                    Object ipAddress = map.get("ipAddress");
                    Object port = map.get("port");
                    Object sonEventType = map.get("sonEventType");
                    Object requestPath = map.get("requestPath");
                    Object eventType = map.get("eventType");
                    Object triggerGroup = map.get("triggerGroup");
                    Object hexadecimal = map.get("hexadecimal");
                    Object delay = map.get("delay");
                    Object audioFilePath = map.get("audioFilePath");
                    Object serialNumber = map.get("serialNumber");
                    Object baudRate = map.get("baudRate");
                    Object dataBits = map.get("dataBits");
                    Object stopBits = map.get("stopBits");
                    Object parityBits = map.get("parityBits");
                    Object infoText = map.get("infoText");
                    Object videoFilePath = map.get("videoFilePath");
                    Object imageFilePath = map.get("imageFilePath");
                    Object variableList = map.get("variableList");
                    Object commandId = map.get("commandId");
                    Object nextCommandId = map.get("nextCommandId");
                    Object trueNextId = map.get("trueNextId");
                    Object falseNextId = map.get("falseNextId");
                    Object firstCommandId = map.get("firstCommandId");
                    Object bufferTime = map.get("bufferTime");
                    Object initialValue = map.get("initialValue");
                    Object targetValue = map.get("targetValue");
                    Object componentType = map.get("componentType");
                    Object aimComponentId = map.get("componentId");
                    Object inputOutputArr = map.get("inputOutputArr");
                    Object y = map.get("y");
                    Object x = map.get("x");
                    Object w = map.get("w");
                    Object h = map.get("h");
                    Object z = map.get("z");
                    Object fontColor = map.get("fontColor");
                    Object textChinese = map.get("textChinese");
                    Object textTraditional = map.get("textTraditional");
                    Object textEnglish = map.get("textEnglish");
                    Object backgroundColor = map.get("backgroundColor");
                    Object background = map.get("background");
                    Object fontSize = map.get("fontSize");
                    Object borderCorner = map.get("borderCorner");

                    TCommand tCommand = new TCommand();
                    if (inputOutputArr != null) {
                        List<Map<String, String>> inputOutputList = (List<Map<String, String>>) inputOutputArr;
                        if (!CollectionUtils.isEmpty(inputOutputList)) {
                            StringBuilder inputOutputString = new StringBuilder();
                            for (Map<String, String> inputOutputItem : inputOutputList) {
                                inputOutputString.append(String.valueOf(inputOutputItem.get("inputValue")) + ">" + String.valueOf(inputOutputItem.get("outputValue")) + "#");
                            }
                            tCommand.setInputOutputArrData(inputOutputString.toString());
                        }
                    }
//                    tCommand.setInputOutputArrData()
                    tCommand.setTargetValue(targetValue == null || targetValue.toString().equals("") ? 0 : Double.parseDouble(targetValue.toString()));
                    tCommand.setInitialValue(initialValue == null || initialValue.toString().equals("") ? 0 : Double.parseDouble(initialValue.toString()));
                    tCommand.setBufferTime(bufferTime == null || bufferTime.toString().equals("") ? 0 : Integer.parseInt(bufferTime.toString()));
                    tCommand.setComponentType(componentType == null ? null : componentType.toString());
                    tCommand.setComponentId(aimComponentId == null ? null : Integer.parseInt(aimComponentId.toString()));
                    tCommand.setY(y == null ? null : Double.parseDouble(y.toString()));
                    tCommand.setX(x == null ? null : Double.parseDouble(x.toString()));
                    tCommand.setW(w == null ? null : Double.parseDouble(w.toString()));
                    tCommand.setH(h == null ? null : Double.parseDouble(h.toString()));
                    tCommand.setZ(z == null ? null : Double.parseDouble(z.toString()));
                    tCommand.setFontColor(fontColor == null ? null : fontColor.toString());
                    tCommand.setTextChinese(textChinese == null ? null : textChinese.toString());
                    tCommand.setTextTraditional(textTraditional == null ? null : textTraditional.toString());
                    tCommand.setTextEnglish(textEnglish == null ? null : textEnglish.toString());
                    tCommand.setBackgroundColor(backgroundColor == null ? null : backgroundColor.toString());
                    tCommand.setBackground(background == null ? null : background.toString());
                    tCommand.setFontSize(fontSize == null ? null : Integer.parseInt(fontSize.toString()));
                    tCommand.setBorderCorner(borderCorner == null ? null : Integer.parseInt(borderCorner.toString()));


                    tCommand.setAudioFilePath(audioFilePath == null ? null : audioFilePath.toString());
                    tCommand.setDelay(delay == null || delay.toString().equals("") ? 0 : Integer.parseInt(delay.toString()));
                    tCommand.setMainType(type);
                    tCommand.setCommandId(commandId == null ? null : commandId.toString());
                    tCommand.setNextCommandId(nextCommandId == null ? null : nextCommandId.toString());
                    tCommand.setTrueNextId(trueNextId == null ? null : trueNextId.toString());
                    tCommand.setFalseNextId(falseNextId == null ? null : falseNextId.toString());
                    tCommand.setMainId(componentId);
                    tCommand.setCommandEvent(commandType);
                    tCommand.setInstructionData(instructionData == null ? null : instructionData.toString());
                    tCommand.setCommandIndex(i);
                    tCommand.setFirstCommandId(firstCommandId == null ? null : firstCommandId.toString());
                    tCommand.setIpAddress(ipAddress == null ? null : ipAddress.toString());
                    tCommand.setPort(port == null ? null : port.toString());
                    tCommand.setEventType(eventType == null ? null : Integer.parseInt(eventType.toString()));
                    tCommand.setSonEventType(sonEventType == null ? null : Integer.parseInt(sonEventType.toString()));
                    tCommand.setReturnFormat(returnFormat == null ? null : returnFormat.toString());
                    tCommand.setBeChangedVariableName(beChangedVariableName == null ? null : beChangedVariableName.toString());
                    tCommand.setBeChangedVariableValue(beChangedVariableValue == null ? null : beChangedVariableValue.toString());
                    tCommand.setTriggerGroup(triggerGroup == null ? null : triggerGroup.toString());
                    tCommand.setHexadecimalData(hexadecimal == null ? 0 : (Boolean) hexadecimal ? 1 : 0);
                    tCommand.setRequestPath(requestPath == null ? null : requestPath.toString());
                    tCommand.setSerialNumber(serialNumber == null ? null : Integer.parseInt(serialNumber.toString()));
                    tCommand.setBaudRate(baudRate == null ? 9600 : Integer.parseInt(baudRate.toString()));
                    tCommand.setDataBits(dataBits == null ? 8 : Integer.parseInt(dataBits.toString()));
                    tCommand.setStopBits(stopBits == null ? 1 : Integer.parseInt(stopBits.toString()));
                    tCommand.setParityBits(parityBits == null ? 0 : Integer.parseInt(parityBits.toString()));
                    tCommand.setInfoText(infoText == null ? null : infoText.toString());
                    tCommand.setVideoFilePath(videoFilePath == null ? null : videoFilePath.toString());
                    tCommand.setImageFilePath(imageFilePath == null ? null : imageFilePath.toString());
                    tCommand.setVariableList(variableList == null ? null : variableList.toString());
                    Object getReturn = map.get("getReturn");
                    tCommand.setGetReturnData(getReturn == null ? null : (Boolean) getReturn ? 1 : 0);
                    List<Map<String, String>> returnValueArr = (List<Map<String, String>>) map.get("returnValueArr");
                    if (!CollectionUtils.isEmpty(returnValueArr)) {
                        StringBuilder returnValueArrStr = new StringBuilder();
                        for (Map<String, String> stringStringMap : returnValueArr) {
                            returnValueArrStr.append(stringStringMap.get("valueName") + "#");
                        }
                        tCommand.setReturnValueArrData(returnValueArrStr.toString());
                    }
                    List<Map<String, String>> inputValueArr = (List<Map<String, String>>) map.get("inputValueArr");
                    if (!CollectionUtils.isEmpty(inputValueArr)) {
                        StringBuilder inputValueArrStr = new StringBuilder();
                        for (Map<String, String> stringStringMap : inputValueArr) {
                            inputValueArrStr.append(stringStringMap.get("valueName") + "#");
                        }
                        tCommand.setInputValueArrData(inputValueArrStr.toString());
                    }
                    tCommandList.add(tCommand);
                }

            }
        });
        saveBatch(tCommandList);
    }

    /**
     * @param
     * @return
     * @Description: 根据组件id获取指令列表
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:21
     */
    @Override
    public List<TCommand> getCommandListByMain(Integer id, String type, String commandEvent) {
        List<TCommand> tCommands = lambdaQuery()
                .eq(TCommand::getMainId, id)
                .eq(TCommand::getMainType, type)
                .eq(TCommand::getCommandEvent, commandEvent)
                .list();
        return tCommands;
    }

    /**
     * @param
     * @return
     * @Description: 补充指令参数
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:21
     */
    @Override
    public List<TCommand> fillTCommands(List<TCommand> clickCommands) {
        clickCommands = clickCommands.stream().map(tCommand -> {
            String returnValueArrData1 = tCommand.getReturnValueArrData();
            if (!StringUtils.isEmpty(returnValueArrData1)) {
                ArrayList<Map<String, String>> returnValueList = new ArrayList<>();
                String[] split = returnValueArrData1.split("#");
                for (String s : split) {
                    HashMap<String, String> map = new HashMap<>();
                    map.put("valueName", s);
                    returnValueList.add(map);
                }
                tCommand.setReturnValueArr(returnValueList);
            }

            String inputValueArrData = tCommand.getInputValueArrData();
            if (!StringUtils.isEmpty(inputValueArrData)) {
                ArrayList<Map<String, String>> inputValueList = new ArrayList<>();
                String[] split = inputValueArrData.split("#");
                for (String s : split) {
                    HashMap<String, String> map = new HashMap<>();
                    map.put("valueName", s);
                    inputValueList.add(map);
                }
                tCommand.setInputValueArr(inputValueList);
            }
            Integer getReturnData = tCommand.getGetReturnData();
            tCommand.setGetReturn(getReturnData == null ? false : getReturnData == 1);
            Integer hexadecimalData = tCommand.getHexadecimalData();
            tCommand.setHexadecimal(hexadecimalData == null ? false : hexadecimalData == 1);
            return tCommand;
        }).collect(Collectors.toList());
        return clickCommands;
    }

    @Override
    public void getCommandListByPageIdAndCommandType(Integer pageId, String commandType) {

    }


    /**
     * @param
     * @param switchsByPageId
     * @param imagesByPageId
     * @param tTextViewsByPageId
     * @param pptsByPageId
     * @param tokenId
     * @Description: 初始化页面
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:22
     */
    @Override
    public void initPage(
            Map<String, Object> variableMap,
            List<TButton> buttonsByPageId,
            List<TSlider> sliderIdsByPageId,
            List<TVideo> videoIdsByPageId,
            List<TWebPage> webPageIdsByPageId,
            List<TSwitch> switchsByPageId,
            List<TImage> imagesByPageId,
            List<TTextView> tTextViewsByPageId,
            List<TPPT> pptsByPageId,
            String tokenId,
            String ip) {
        List<Integer> buttonIds = buttonsByPageId.stream().map(TButton::getId).collect(Collectors.toList());
        List<Integer> sliderIds = sliderIdsByPageId.stream().map(TSlider::getId).collect(Collectors.toList());
        List<Integer> videoIds = videoIdsByPageId.stream().map(TVideo::getId).collect(Collectors.toList());
        List<Integer> webPageIds = webPageIdsByPageId.stream().map(TWebPage::getId).collect(Collectors.toList());
        List<Integer> switchIds = switchsByPageId.stream().map(TSwitch::getId).collect(Collectors.toList());
        List<Integer> imageIds = imagesByPageId.stream().map(TImage::getId).collect(Collectors.toList());
        List<Integer> tTextViewIds = tTextViewsByPageId.stream().map(TTextView::getId).collect(Collectors.toList());
        List<Integer> pptIds = pptsByPageId.stream().map(TPPT::getId).collect(Collectors.toList());
        List<TCommand> initCommandList = new ArrayList<>();
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, buttonIds)
                .eq(TCommand::getMainType, "BUTTON")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, sliderIds)
                .eq(TCommand::getMainType, "SLIDER")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, videoIds)
                .eq(TCommand::getMainType, "VIDEO")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, webPageIds)
                .eq(TCommand::getMainType, "WEBPAGE")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, pptIds)
                .eq(TCommand::getMainType, "PPT")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, switchIds)
                .eq(TCommand::getMainType, "SWITCH")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, imageIds)
                .eq(TCommand::getMainType, "IMAGE")
                .eq(TCommand::getCommandEvent, "init")
                .list());
        initCommandList.addAll(lambdaQuery()
                .in(TCommand::getMainId, tTextViewIds)
                .eq(TCommand::getMainType, "TEXTVIEW")
                .eq(TCommand::getCommandEvent, "init")
                .list());


        executeCommandsAndGetReply(initCommandList, variableMap, tokenId, ip);
    }

    /**
     * @param
     * @return
     * @Description: 根据组件ID删除对应的指令
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:23
     */
    @Override
    public void delCommandsByMain(Set<Integer> mainIds, String mainType) {
        QueryWrapper<TCommand> delWrapper = new QueryWrapper<>();
        delWrapper.lambda().in(TCommand::getMainId, mainIds).eq(TCommand::getMainType, mainType);
        remove(delWrapper);
    }

    /**
     * @param
     * @return
     * @Description: 保存指令列表
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:24
     */
    @Override
    public void saveCommandList(List<TCommand> commandList) {
        saveBatch(commandList);
    }

    @Autowired
    private TButtonMapper tButtonMapper;


    /**
     * @param
     * @Description: 指令单个指令并获取返回值
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:25
     */
    @Override
    public void executeSingleCommandAndGetReply(TCommand tCommand, Map<String, Object> variableMap, String wsToken,String ip) {
        try {
            String variableList = tCommand.getVariableList();
            if (variableList == null) {
                variableList = "";
            }
            String instructionData = null;
            if (StringUtils.isEmpty(variableList) || !variableList.contains("instructionData")) {
                instructionData = tCommand.getInstructionData();
            } else {
                instructionData = assignVariable(variableMap, tCommand.getInstructionData());
            }
            String inputValueArrData = tCommand.getInputValueArrData();
            String beChangedVariableValue = tCommand.getBeChangedVariableValue();
            if (!StringUtils.isEmpty(inputValueArrData)) {
                String[] split = inputValueArrData.split("#");
                if (split != null && split.length > 0) {
                    ScriptEngineManager manager = new ScriptEngineManager();
                    ScriptEngine engine = manager.getEngineByName("JavaScript");
                    SimpleBindings bindings = new SimpleBindings();
                    variableMap.forEach(new BiConsumer<String, Object>() {
                        @Override
                        public void accept(String s, Object aDouble) {
                            if (aDouble == null) {
                                return;
                            }
                            bindings.put(s, aDouble.toString());
                        }
                    });
                    List<String> resInJEPList = new ArrayList<>();


                    for (int i = 0; i < split.length; i++) {
                        String s = split[i];
                        Object result = engine.eval(s, bindings);
                        resInJEPList.add(result.toString());
                    }

                    int index;
                    int count = 0;
                    if (tCommand.getEventType() != 3) {
                        while ((index = instructionData.indexOf("?")) != -1) {
                            String value = resInJEPList.get(count++);
                            instructionData = instructionData
                                    .replaceFirst(
                                            "\\?",
                                            value == null ? "" : value
                                    );
                        }
                    } else {
                        while ((index = beChangedVariableValue.indexOf("?")) != -1) {
                            String value = resInJEPList.get(count++);
                            beChangedVariableValue = beChangedVariableValue
                                    .replaceFirst(
                                            "\\?",
                                            value == null ? "" : value
                                    );
                        }
                    }

                }
            }
            Integer eventType = tCommand.getEventType();
            byte[] instructionByte = null;
            if (!StringUtils.isEmpty(instructionData)) {
                Integer hexadecimalData = tCommand.getHexadecimalData();
                if (hexadecimalData == 1) {
                    instructionByte = hexStringToByteArray(instructionData.replaceAll(" ", ""));
                } else {
                    instructionByte = instructionData.getBytes();
                }
            }
            String res = null;
            Map<String, Object> resMap = new HashMap<>();
//            判断是否需要延时
            Integer delay = tCommand.getDelay();
            if (delay != null && delay > 0) {
                Thread.sleep(delay);
            }
            String ipAddress = null;
            Integer port = null;
            String requestPath = null;
            String triggerGroup = null;
            String audioFilePath = null;
            String serialNumber = null;
            String baudRate = null;
            String dataBits = null;
            String stopBits = null;
            String parityBits = null;
            switch (eventType) {
                case 0:
                    ipAddress = tCommand.getIpAddress();
                    port = Integer.parseInt(tCommand.getPort());
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("ipAddress")) {
                        ipAddress = assignVariable(variableMap, tCommand.getIpAddress());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("port")) {
                        port = Integer.parseInt(assignVariable(variableMap, tCommand.getPort()));
                    }
                    res = TCPSender.send(ipAddress, port, instructionByte, tCommand.getGetReturnData() == 1, wsToken);
                    break;
                case 1:
                    ipAddress = tCommand.getIpAddress();
                    port = Integer.parseInt(tCommand.getPort());
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("ipAddress")) {
                        ipAddress = assignVariable(variableMap, tCommand.getIpAddress());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("port")) {
                        port = Integer.parseInt(assignVariable(variableMap, tCommand.getPort()));
                    }
                    if (tCommand.getSonEventType() == 0) {
                        res = UDPSender.send(ipAddress, port, instructionByte, tCommand.getGetReturnData() == 1);
                    }
                    if (tCommand.getSonEventType() == 1) {
                        res = UDPSender.sendInGroup(ipAddress, port, instructionByte, tCommand.getGetReturnData() == 1);
                    }
                    if (tCommand.getSonEventType() == 2) {
                        res = UDPSender.sendInBoardCast("255.255.255.255", port, instructionByte);
                    }
                    break;
                case 2:
                    ipAddress = tCommand.getIpAddress();
                    port = Integer.parseInt(tCommand.getPort());
                    requestPath = tCommand.getRequestPath();
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("ipAddress")) {
                        ipAddress = assignVariable(variableMap, tCommand.getIpAddress());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("port")) {
                        port = Integer.parseInt(assignVariable(variableMap, tCommand.getPort()));
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("requestPath")) {
                        requestPath = assignVariable(variableMap, tCommand.getRequestPath());
                    }
                    if (tCommand.getSonEventType() == 0) {
                        res = HTTPSender.sendWithGET(ipAddress, port, instructionByte, requestPath, tCommand.getGetReturnData() == 1);
                    }
                    if (tCommand.getSonEventType() == 1) {
                        res = HTTPSender.sendWithPOST(ipAddress, port, instructionByte, requestPath, tCommand.getGetReturnData() == 1);
                    }
                    if (tCommand.getSonEventType() == 2) {
                        res = HTTPSender.sendWithPUT(ipAddress, port, instructionByte, requestPath, tCommand.getGetReturnData() == 1);
                    }
                    if (tCommand.getSonEventType() == 3) {
                        res = HTTPSender.sendWithDELETE(ipAddress, port, instructionByte, requestPath, tCommand.getGetReturnData() == 1);
                    }
                    break;
                case 3:
                    tCommand.setGetReturnData(1);
                    tCommand.setReturnFormat("?");
                    res = beChangedVariableValue;
                    tCommand.setReturnValueArrData(tCommand.getBeChangedVariableName() + "#");
                    break;
                case 4:
                    triggerGroup = tCommand.getTriggerGroup();
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("triggerGroup")) {
                        triggerGroup = assignVariable(variableMap, tCommand.getTriggerGroup());
                    }
                    Integer mainId = tCommand.getMainId();
                    Integer pageId = tButtonMapper.getPageIdByButtonId(mainId);
                    List<TButton> buttons = tButtonMapper.getButtonsByPageIdAndGroupName(pageId, triggerGroup);
                    for (TButton tButton : buttons) {
                        List<TCommand> commandList = getCommandListByMain(tButton.getId(), tButton.getType(), "click");
                        executeCommandsAndGetReply(commandList, variableMap, null, ip);
                    }
                    return;
                case 5:
                    audioFilePath = tCommand.getAudioFilePath();
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("audioFilePath")) {
                        audioFilePath = assignVariable(variableMap, tCommand.getAudioFilePath());
                    }
                    NetworkAudioPlayer.play("http://127.0.0.1:9000/" + audioFilePath);
                    break;
                case 6:
                    serialNumber = tCommand.getSerialNumber().toString();
                    baudRate = tCommand.getBaudRate().toString();
                    dataBits = tCommand.getDataBits().toString();
                    stopBits = tCommand.getStopBits().toString();
                    parityBits = tCommand.getParityBits().toString();
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("serialNumber")) {
                        serialNumber = assignVariable(variableMap, tCommand.getSerialNumber().toString());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("baudRate")) {
                        baudRate = assignVariable(variableMap, tCommand.getBaudRate().toString());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("dataBits")) {
                        dataBits = assignVariable(variableMap, tCommand.getDataBits().toString());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("stopBits")) {
                        stopBits = assignVariable(variableMap, tCommand.getStopBits().toString());
                    }
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("parityBits")) {
                        parityBits = assignVariable(variableMap, tCommand.getParityBits().toString());
                    }
                    RS485Util.send(Integer.parseInt(serialNumber), instructionByte, Integer.parseInt(baudRate), Integer.parseInt(dataBits), Integer.parseInt(stopBits), Integer.parseInt(parityBits));
                    break;
                case 8:
                    CommandLineUtil.executeCommand(instructionData);
                    break;
                case 9:
                    executeJSCode(variableMap, instructionData);
                    break;
                case 10:
                    ipAddress = tCommand.getIpAddress();
                    if (!StringUtils.isEmpty(variableList) && variableList.contains("ipAddress")) {
                        ipAddress = assignVariable(variableMap, tCommand.getIpAddress());
                    }
                    UDPSender.wakeUp(instructionData, ipAddress);
                    break;
                case 12:
//                    修改目标组件的样式
                    changeComponentStyle(tCommand, variableMap, variableList);
                    break;
                case 13:
                    Boolean exists = false;
                    ConcurrentHashMap<String, Set<String>> pathMapClient = WebSocketServer.pathMapClient;
                    for (String pageName : pathMapClient.keySet()) {
                        if (pathMapClient.get(pageName).contains(wsToken)) {
                            exists = true;
                            break;
                        }
                    }
                    if (!exists) {
                        CommandController.runMap.remove(ip);
                        System.out.println("页面对象已经销毁");
                        return;
                    }
                    WSResult<HashMap<String, Object>> commandRes = new WSResult<>();
                    HashMap<String, Object> messageMap = new HashMap<>();
                    messageMap.put("type", "message");
                    messageMap.put("data", instructionData);
                    commandRes.setData(messageMap);
                    WebSocketServer.sendInfo(commandRes, wsToken);
                    break;
                case 14:
                    String bufferTime = tCommand.getBufferTime().toString();
                    String beChangedVariableName = tCommand.getBeChangedVariableName();
                    String initialValue = tCommand.getInitialValue().toString();
                    String targetValue = tCommand.getTargetValue().toString();
                    if (!StringUtils.isEmpty(bufferTime) && variableList.contains("bufferTime")) {
                        bufferTime = assignVariable(variableMap, bufferTime);
                    }
                    if (!StringUtils.isEmpty(beChangedVariableName) && variableList.contains("beChangedVariableName")) {
                        beChangedVariableName = assignVariable(variableMap, beChangedVariableName);
                    }
                    if (StringUtils.isEmpty(initialValue) && variableList.contains("initialValue")) {
                        initialValue = assignVariable(variableMap, initialValue);
                    }
                    if (StringUtils.isEmpty(targetValue) && variableList.contains("targetValue")) {
                        targetValue = assignVariable(variableMap, targetValue);
                    }
                    startSmoothTransition(bufferTime, beChangedVariableName, initialValue, targetValue, variableMap, wsToken);
                    break;
                case 15:
                    String componentId = tCommand.getComponentId().toString();

                    if (!StringUtils.isEmpty(componentId) && variableList.contains("componentId")) {
                        componentId = assignVariable(variableMap, componentId);
                    }

                    List<HashMap<String, Object>> switchList = (List<HashMap<String, Object>>) variableMap.get("switchList");
                    String targetSwitchValue = null;
                    String switchVariableName = switchList.get(Integer.parseInt(componentId)).get("switchVariable").toString();
                    String sourceSwitchValue = variableMap.get(switchVariableName) == null ? "0" : variableMap.get(switchVariableName).toString();
                    switch (instructionData) {
                        case "0":
                            targetSwitchValue = sourceSwitchValue.equals("0") ? "1" : "0";
                            break;
                        case "1":
                            targetSwitchValue = "0";
                            break;
                        case "2":
                            targetSwitchValue = "1";
                            break;
                    }
                    variableMap.put(switchVariableName, targetSwitchValue);
                    break;
                case 16:
                    String beChangedVariableNameInVT = tCommand.getBeChangedVariableName();
                    String inputOutputArrData = tCommand.getInputOutputArrData();
                    if (!StringUtils.isEmpty(beChangedVariableNameInVT) && variableList.contains("beChangedVariableName")) {
                        beChangedVariableNameInVT = assignVariable(variableMap, beChangedVariableNameInVT);
                    }

                    HashMap<String, String> inputMapOutput = new HashMap<>();
                    if (!StringUtils.isEmpty(inputOutputArrData)) {
                        String[] split = inputOutputArrData.split("#");
                        for (String inputOutputItem : split) {
                            String[] inputOutputItemPart = inputOutputItem.split(">");
                            inputMapOutput.put(inputOutputItemPart[0], inputOutputItemPart[1]);
                        }
                    }

                    String targetValueInVT = inputMapOutput.get(instructionData);

                    variableMap.put(beChangedVariableNameInVT, targetValueInVT);
                    break;
            }
            if (tCommand.getGetReturnData() == null || tCommand.getGetReturnData() == 0) {
                return;
            }
            String returnFormat = tCommand.getReturnFormat();
            List<String> extractRes = InputExtractor.extract(returnFormat.replace("?", "(.*)"), res, countCharOccurrences(returnFormat, '?'));
            String returnValueArrData = tCommand.getReturnValueArrData();
            String[] returnVariableNameArr = returnValueArrData.split("#");

            for (int i = 0; i < returnVariableNameArr.length; i++) {
                String s = returnVariableNameArr[i];
                try {
                    String value = extractRes.get(i);
                    variableMap.put(s, value);
                } catch (Exception e) {
                    variableMap.put(s, null);
                }
            }
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startSmoothTransition(String bufferTime, String beChangedVariableName, String initialValueStr, String targetValueStr, Map<String, Object> variableMap, String wsToken) {
        long bufferTimeNum = Long.parseLong(bufferTime);
        double initialValueNum = Double.parseDouble(initialValueStr);
        double targetValueNum = Double.parseDouble(targetValueStr);
        SmoothValueTransition smoothValueTransition = new SmoothValueTransition();
        smoothValueTransition.startSmoothTransition(initialValueNum, targetValueNum, bufferTimeNum, wsToken, beChangedVariableName, variableMap);

    }

    private void changeComponentStyle(TCommand tCommand, Map<String, Object> variableMap, String variableList) throws ScriptException {
        String componentType = tCommand.getComponentType();
        Integer componentId = tCommand.getComponentId();
        Double y = tCommand.getY();
        Double x = tCommand.getX();
        Double w = tCommand.getW();
        Double h = tCommand.getH();
        Double z = tCommand.getZ();
        String fontColor = tCommand.getFontColor();
        String textChinese = tCommand.getTextChinese();
        String textTraditional = tCommand.getTextTraditional();
        String textEnglish = tCommand.getTextEnglish();
        String backgroundColor = tCommand.getBackgroundColor();
        String background = tCommand.getBackground();
        Integer fontSize = tCommand.getFontSize();
        Integer borderCorner = tCommand.getBorderCorner();
        if (!StringUtils.isEmpty(variableList) && variableList.contains("componentType")) {
            componentType = assignVariable(variableMap, componentType);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("componentId")) {
            componentId = Integer.parseInt(assignVariable(variableMap, componentId.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("y")) {
            y = Double.parseDouble(assignVariable(variableMap, y.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("x")) {
            x = Double.parseDouble(assignVariable(variableMap, x.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("w")) {
            w = Double.parseDouble(assignVariable(variableMap, w.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("h")) {
            h = Double.parseDouble(assignVariable(variableMap, h.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("z")) {
            z = Double.parseDouble(assignVariable(variableMap, z.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("fontColor")) {
            fontColor = assignVariable(variableMap, fontColor);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("textChinese")) {
            textChinese = assignVariable(variableMap, textChinese);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("textTraditional")) {
            textTraditional = assignVariable(variableMap, textTraditional);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("textEnglish")) {
            textEnglish = assignVariable(variableMap, textEnglish);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("backgroundColor")) {
            backgroundColor = assignVariable(variableMap, backgroundColor);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("background")) {
            background = assignVariable(variableMap, background);
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("fontSize")) {
            fontSize = Integer.parseInt(assignVariable(variableMap, fontSize.toString()));
        }
        if (!StringUtils.isEmpty(variableList) && variableList.contains("borderCorner")) {
            borderCorner = Integer.parseInt(assignVariable(variableMap, borderCorner.toString()));
        }
        switch (componentType) {
            case "BUTTON":
                List<Map<String, Object>> buttonList = (List<Map<String, Object>>) variableMap.get("buttonList");
                Map<String, Object> buttonMap = buttonList.get(componentId);
                Double pageRealHeight = Double.parseDouble(variableMap.get("pageRealHeight").toString());
                Double pageRealWidth = Double.parseDouble(variableMap.get("pageRealWidth").toString());
                Double pageSourceHeight = Double.parseDouble(variableMap.get("pageSourceHeight").toString());
                Double pageSourceWidth = Double.parseDouble(variableMap.get("pageSourceWidth").toString());
                buttonMap.put("y", Math.floor((y * pageRealHeight) / pageSourceHeight));
                buttonMap.put("x", Math.floor((x * pageRealWidth) / pageSourceWidth));
                buttonMap.put("w", Math.floor((w * pageRealWidth) / pageSourceWidth));
                buttonMap.put("h", Math.floor((h * pageRealHeight) / pageSourceHeight));


                buttonMap.put("z", z);
                buttonMap.put("fontColor", fontColor);
                buttonMap.put("textChinese", textChinese);
                buttonMap.put("textTraditional", textTraditional);
                buttonMap.put("textEnglish", textEnglish);
                buttonMap.put("backgroundColor", backgroundColor);
                buttonMap.put("background", background);
                buttonMap.put("fontSize", fontSize);
                buttonMap.put("borderCorner", borderCorner);
                break;

        }
    }

    private void executeJSCode(Map<String, Object> variableMap, String instructionData) {
        // 创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();
        // 获取一个 JavaScript 脚本引擎
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        for (Map.Entry<String, Object> entry : variableMap.entrySet()) {
            engine.put(entry.getKey(), entry.getValue());
        }

        try {
            // 定义一个脚本，声明多个变量
            String script =
                    instructionData;

            // 执行脚本
            engine.eval(script);

            // 获取脚本中的全局变量绑定
            Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);

            // 遍历 Bindings 中的所有变量
            System.out.println("Variables in the script:");
            for (String key : bindings.keySet()) {
                if (variableMap.containsKey(key)) {
                    variableMap.put(key, bindings.get(key));
                }
            }
            System.out.println(variableMap);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

    private String assignVariable(Map<String, Object> variableMap, String expression) throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        SimpleBindings bindings = new SimpleBindings();
        variableMap.forEach(new BiConsumer<String, Object>() {
            @Override
            public void accept(String s, Object aDouble) {
                if (aDouble == null) {
                    return;
                }
                try {
                    bindings.put(s, JSONObject.parseObject(aDouble.toString(), Map.class));
//                    System.out.println("解析为Map对象");
                } catch (Exception e) {
                    bindings.put(s, aDouble.toString());
//                    System.out.println("解析为普通字符串");
                }
            }
        });
        List<String> resInJEPList = new ArrayList<>();
        Object result = engine.eval(expression, bindings);
        resInJEPList.add(result.toString());
        return result.toString();
    }

    /**
     * @param
     * @param ip
     * @Description: 执行指令列表并获取返回值
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:26
     */
    @Override
    public void executeCommandsAndGetReply(List<TCommand> commandList, Map<String, Object> variableMap, String wsToken, String ip) {
        if (CollectionUtils.isEmpty(commandList)) {
            try {
                CommandController.runMap.remove(ip);
                WSResult<HashMap<String, Object>> commandRes = new WSResult<>();
                HashMap<String, Object> resMap = new HashMap<>();
                resMap.put("type", "endProgress");
                commandRes.setData(resMap);
                WebSocketServer.sendInfo(commandRes, wsToken);
            } catch (IOException | EncodeException e) {
                e.printStackTrace();
            }
            return;
        }
        int index = 0;
        Set<String> firstCommandIdList = commandList.stream().map(tCommand -> {
            return tCommand.getMainType()+"-"+tCommand.getMainId()+"-"+tCommand.getFirstCommandId();
        }).collect(Collectors.toSet());
        HashMap<String, List<TCommand>> firstCommandIdMapCommandList = new HashMap<>();
        for (TCommand tCommand : commandList) {
            String firstCommandId = tCommand.getFirstCommandId();
            String mainType = tCommand.getMainType();
            Integer mainId = tCommand.getMainId();
            String key = mainType + "-" + mainId + "-" + firstCommandId;
            List<TCommand> list = firstCommandIdMapCommandList.get(key);
            if (CollectionUtils.isEmpty(list)) {
                list = new ArrayList<>();
                firstCommandIdMapCommandList.put(key, list);
            }
            list.add(tCommand);
        }
        for (String nextCommandId : firstCommandIdList) {
            List<TCommand> list = firstCommandIdMapCommandList.get(nextCommandId);
            Map<String, TCommand> commandIdMapCommand = list.stream().collect(Collectors.toMap(TCommand::getCommandId, t -> t));
            String[] arr = nextCommandId.split("-");
            nextCommandId = arr[arr.length - 1];
            while (!StringUtils.isEmpty(nextCommandId)) {
                TCommand tCommand = commandIdMapCommand.get(nextCommandId);
                if (tCommand.getEventType() != 11) {
                    nextCommandId = tCommand.getNextCommandId();
                } else {
                    String instructionData = tCommand.getInstructionData();
                    try {
                        Boolean res = Boolean.parseBoolean(assignVariable(variableMap, instructionData));
                        nextCommandId = res ? tCommand.getTrueNextId() : tCommand.getFalseNextId();
                        continue;
                    } catch (ScriptException e) {
                        e.printStackTrace();
                        nextCommandId = null;
                        continue;
                    }
                }
                executeSingleCommandAndGetReply(tCommand, variableMap, wsToken,ip);
                try {
                    Boolean exists = false;
                    ConcurrentHashMap<String, Set<String>> pathMapClient = WebSocketServer.pathMapClient;
                    for (String pageName : pathMapClient.keySet()) {
                        if (pathMapClient.get(pageName).contains(wsToken)) {
                            exists = true;
                            break;
                        }
                    }
                    if (!exists) {
                        System.out.println("页面对象已经销毁");
                        CommandController.runMap.remove(ip);
                        return;
                    }
                    WSResult<HashMap<String, Object>> commandRes = new WSResult<>();
                    HashMap<String, Object> resMap = new HashMap<>();
                    resMap.put("type", "commandResult");
                    resMap.put("data", variableMap);
                    resMap.put("progress", ++index);
                    commandRes.setData(resMap);
                    WebSocketServer.sendInfo(commandRes, wsToken);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (EncodeException e) {
                    e.printStackTrace();
                }


            }
        }
        try {
            CommandController.runMap.remove(ip);
            WSResult<HashMap<String, Object>> commandRes = new WSResult<>();
            HashMap<String, Object> resMap = new HashMap<>();
            resMap.put("type", "endProgress");
            commandRes.setData(resMap);
            WebSocketServer.sendInfo(commandRes, wsToken);
        } catch (IOException | EncodeException e) {
            e.printStackTrace();
        }
//        return variableMap;
    }

    @Override
    public void executeCommandsAndGetReplyOfAudio(List<TCommand> commandList, Map<String, Object> variableMap, String wsToken,String ip) {
        if (CollectionUtils.isEmpty(commandList)) {
            return;
        }
        for (TCommand tCommand : commandList) {

            executeSingleCommandAndGetReply(tCommand, variableMap, wsToken,ip);
            try {
                Boolean exists = false;
                ConcurrentHashMap<String, Set<String>> pathMapClient = WebSocketServer.pathMapClient;
                for (String pageName : pathMapClient.keySet()) {
                    if (pathMapClient.get(pageName).contains(wsToken)) {
                        exists = true;
                        break;
                    }
                }
                if (!exists) {
                    CommandController.runMap.remove(ip);
                    System.out.println("页面对象已经销毁");
                    return;
                }
                WSResult<HashMap<String, Object>> commandRes = new WSResult<>();
                HashMap<String, Object> resMap = new HashMap<>();
                resMap.put("type", "commandResult");
                resMap.put("data", variableMap);
                commandRes.setData(resMap);
                WebSocketServer.sendInfo(commandRes, wsToken);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (EncodeException e) {
                e.printStackTrace();
            }


        }
    }


    public static int countCharOccurrences(String input, char targetChar) {
        return input.length() - input.replace(String.valueOf(targetChar), "").length();
    }
}
